package com.zbl.zblproject.erp.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.Stopwatch;
import com.zbl.zblproject.core.entity.SmallUnit;
import com.zbl.zblproject.core.mapper.*;
import com.zbl.zblproject.erp.entity.*;
import com.zbl.zblproject.erp.mapper.*;
import com.zbl.zblproject.erp.service.ErpGoodService;
import com.zbl.zblproject.erp.service.ErpTableService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author youlanqiang
 * @version 1.0
 * @date 2018/10/23
 */
@Service
@Transactional
public class ErpTableServiceImpl implements ErpTableService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private SupplierMapper supplierMapper;

    @Autowired
    private AdminUserMapper adminUserMapper;

    @Autowired
    private ErpCategoryMapper erpCategoryMapper;

    @Autowired
    private BrandMapper erpBrandMapper;

    @Autowired
    private SupplierMapper erpSupplierMapper;

    @Autowired
    private ErpGoodMapper goodMapper;

    @Autowired
    private ErpOrderMapper erpOrderMapper;

    @Autowired
    private ErpOrderItemMapper orderItemMapper;

    @Autowired
    private ErpWarehouseMapper warehouseMapper;

    @Autowired
    private ErpGoodService goodService;

    @Autowired
    private ErpInventoryOrderMapper inventoryOrderMapper;

    @Autowired
    private ErpInventoryOrderItemMapper inventoryOrderItemMapper;


    @Autowired
    private ErpOweGoodsItemMapper erpOweGoodsItemMapper;

    @Autowired
    private SmallUnitMapper smallUnitMapper;

    private static final Logger logger = LoggerFactory.getLogger(ErpTableServiceImpl.class);


    @Override
    public IPage<ErpStockTable> getStockTableByTime(LocalDateTime start, LocalDateTime end, int current, int size) {

        current = (current - 1) * size;
        //这里出现问题
        List<ErpStockTable> tables = getAllStockTable(start, end);
        List<ErpStockTable> list =  tables.stream().skip(current).limit(size).collect(Collectors.toList());

        IPage<ErpStockTable> page  = new Page<>(current, size);
        page.setTotal(tables.size());
        page.setRecords(list);

        return page;
    }

    @Override
    @Cacheable(value = "app", key = "'stock-table' +#start + #end + #current + #size + #mode ", sync = true)
    public IPage<ErpStockTable> getStockTableByTimeAndMode(LocalDateTime start, LocalDateTime end, int current, int size, int mode) {

        //这里出现问题
        return getAllStockTable(start, end, mode, current, size);
    }

    public List<ErpStockTable> getAllStockTable(LocalDateTime start, LocalDateTime end){
        List<ErpStockTable> tables = new ArrayList<>();
        //出入库订单
        QueryWrapper<ErpOrder> wrapper = new QueryWrapper<>();
        wrapper.eq("status", 2)
                .between("create_time", start, end);
        List<ErpOrder> orders = erpOrderMapper.selectList(wrapper);
        orders.forEach(x->{
            ErpStockTable table = new ErpStockTable();
            table.setOrder(x);
            table.setList(getOrderItemById(x.getOrderId()));
            tables.add(table);
        });

        //盘库, 报损， 领用, 退货
        QueryWrapper<ErpInventoryOrder> inventoryWrapper = new QueryWrapper<>();
        inventoryWrapper.eq("status", 2).between("create_time", start, end);
        List<ErpInventoryOrder> inventoryOrders = inventoryOrderMapper.selectList(inventoryWrapper);
        inventoryOrders.forEach(x->{
            ErpStockTable table = new ErpStockTable();
            table.setOrder(new ErpOrder(x));
            table.setList(getOrderItemByInventId(x));
            tables.add(table);
        });
        return tables;
    }

    public IPage<ErpStockTable> getAllStockTable(LocalDateTime start, LocalDateTime end, int mode, int current, int size){
        Page page = new Page(current, size);
        List<ErpStockTable> tables = new ArrayList<>();
        if(mode == 0){
            //入库
            QueryWrapper<ErpOrder> wrapper = new QueryWrapper<>();
            wrapper.eq("status", 2).eq("mode", 0)
                    .between("create_time", start, end);
            IPage<ErpOrder> orders = erpOrderMapper.selectPage(page, wrapper);
            orders.getRecords().forEach(x->{
                ErpStockTable table = new ErpStockTable();
                table.setOrder(x);
                table.setList(getOrderItemById(x.getOrderId()));
                tables.add(table);
            });
            page.setRecords(tables);
            page.setTotal(orders.getTotal());
            // 18.52s
        }else if(mode == 1){
            //出库
            QueryWrapper<ErpOrder> wrapper = new QueryWrapper<>();
            wrapper.eq("status", 2).eq("mode", 1)
                    .between("create_time", start, end);
            IPage<ErpOrder> orders = erpOrderMapper.selectPage(page, wrapper);
            orders.getRecords().forEach(x->{
                ErpStockTable table = new ErpStockTable();
                table.setOrder(x);
                table.setList(getOrderItemById(x.getOrderId()));
                tables.add(table);
            });
            page.setRecords(tables);
            page.setTotal(orders.getTotal());
        }else if(mode == 2){
            //盘库
            QueryWrapper<ErpInventoryOrder> inventoryWrapper = new QueryWrapper<>();
            inventoryWrapper.eq("mode", 0).eq("status", 2).between("create_time", start, end);
            IPage<ErpInventoryOrder> inventoryOrders = inventoryOrderMapper.selectPage(page, inventoryWrapper);
            inventoryOrders.getRecords().forEach(x->{
                ErpStockTable table = new ErpStockTable();
                table.setOrder(new ErpOrder(x));
                table.setList(getOrderItemByInventId(x));
                tables.add(table);
            });
            page.setRecords(tables);
            page.setTotal(inventoryOrders.getTotal());
        }else if(mode == 3){
            //报损
            QueryWrapper<ErpInventoryOrder> inventoryWrapper = new QueryWrapper<>();
            inventoryWrapper.eq("mode", 1).eq("status", 2).between("create_time", start, end);
            IPage<ErpInventoryOrder> inventoryOrders = inventoryOrderMapper.selectPage(page, inventoryWrapper);
            inventoryOrders.getRecords().forEach(x->{
                ErpStockTable table = new ErpStockTable();
                table.setOrder(new ErpOrder(x));
                table.setList(getOrderItemByInventId(x));
                tables.add(table);
            });
            page.setRecords(tables);
            page.setTotal(inventoryOrders.getTotal());
        }else if(mode == 4){
            //领用
            QueryWrapper<ErpInventoryOrder> inventoryWrapper = new QueryWrapper<>();
            inventoryWrapper.eq("mode", 2).eq("status", 2).between("create_time", start, end);
            IPage<ErpInventoryOrder> inventoryOrders = inventoryOrderMapper.selectPage(page, inventoryWrapper);
            inventoryOrders.getRecords().forEach(x->{
                ErpStockTable table = new ErpStockTable();
                table.setOrder(new ErpOrder(x));
                table.setList(getOrderItemByInventId(x));
                tables.add(table);
            });
            page.setRecords(tables);
            page.setTotal(inventoryOrders.getTotal());
        }else if(mode == 5){
            //退货
            QueryWrapper<ErpInventoryOrder> inventoryWrapper = new QueryWrapper<>();
            inventoryWrapper.eq("mode", 3).eq("status", 2).between("create_time", start, end);
            IPage<ErpInventoryOrder> inventoryOrders = inventoryOrderMapper.selectPage(page, inventoryWrapper);
            inventoryOrders.getRecords().forEach(x->{
                ErpStockTable table = new ErpStockTable();
                table.setOrder(new ErpOrder(x));
                table.setList(getOrderItemByInventId(x));
                tables.add(table);
            });
            page.setRecords(tables);
            page.setTotal(inventoryOrders.getTotal());
        }else{
            throw new NullPointerException("mode is exception");
        }

        return page;
    }

    @Override
    public IPage<ErpGoods> getZombieGoodsByLastTime(LocalDateTime time, int current, int size) {
        IPage<ErpGoods> page = new Page<>(current, size);

        List<Integer> ids = orderItemMapper.selectGoodsIdByLastTime(time);
        QueryWrapper<ErpGoods> wrapper = new QueryWrapper<>();
        wrapper.ne("goods_number", 0).notIn("goods_id", ids);
        page = goodMapper.selectPage(page, wrapper);
        List<ErpGoods> goods =  page.getRecords();
        goods.forEach(x->{
            x.setErpBrand(erpBrandMapper.selectById(x.getBrandId()));
            x.setErpCategory(erpCategoryMapper.selectById(x.getCatId()));
            x.setErpSupplier(erpSupplierMapper.selectById(x.getSuppliersId()));
            x.setSmallUnitName(smallUnitMapper.selectById(x.getSmallunitId()).getName());
        });
        return page;
    }


    @Override
    public ErpOweTableContainer getAllOweTable() {
        List<ErpOweGoodsItem> items = erpOweGoodsItemMapper.selectList(null);
        ErpOweTableContainer container = new ErpOweTableContainer(orderMapper, adminUserMapper, supplierMapper);
        items.forEach(x->{
            x.setGoods(goodMapper.selectById(x.getGoodsId()));
            container.addErpOweItem(x);
        });
        return container;
    }

    private List<ErpOweGoodsItem> getOweGoodsItems(String orderSn){
        QueryWrapper<ErpOweGoodsItem> wrapper = new QueryWrapper<>();
        wrapper.eq("order_sn", orderSn);
        return erpOweGoodsItemMapper.selectList(wrapper);
    }

    private List<ErpOrderItem> getOrderItemByInventId(ErpInventoryOrder order){
        List<ErpOrderItem> items = new ArrayList<>();
        QueryWrapper<ErpInventoryOrderItem> wrapper = new QueryWrapper<>();
        wrapper.eq("order_id", order.getId());
        List<ErpInventoryOrderItem> list = inventoryOrderItemMapper.selectList(wrapper);
        list.forEach(x->{
            ErpOrderItem item = new ErpOrderItem(order.getMode(), x);
            item.setGoods(goodService.selectById(x.getGoodsId()));

            SmallUnit unit =  smallUnitMapper.selectById(item.getGoods().getSmallunitId());
            if(unit == null){
                item.getGoods().setSmallUnitName("个");
            }else{
                item.getGoods().setSmallUnitName(unit.getName());
            }
            item.setWarehouse(warehouseMapper.selectById(x.getWhId()));
            items.add(item);
        });
        return items;
    }

    public List<ErpOrderItem> getOrderItemById(int orderId){
        QueryWrapper<ErpOrderItem> wrapper = new QueryWrapper<>();
        wrapper.eq("order_id", orderId).eq("is_give", 0);
        List<ErpOrderItem> items = orderItemMapper.selectList(wrapper);
        Stopwatch stopwatch = Stopwatch.createStarted();
        items.forEach(x->{
            x.setGoods(goodService.selectById(x.getGoodsId()));
            x.setWarehouse(warehouseMapper.selectById(x.getGoodsList()));
        });
        stopwatch.stop();
        logger.info("毫时:{}, 订单ID:{}, 订单数量:{}",stopwatch.toString(), orderId, items.size());
        return items;
    }


}
